package dongbai.soft.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import dongbai.soft.entity.LineEntity;
import dongbai.soft.entity.OrderEntity;
import dongbai.soft.entity.StaticsEntity;
import dongbai.soft.entity.TransferEntity;
import dongbai.soft.feigncilent.CustomerClient;
import dongbai.soft.feigncilent.ShedClient;
import dongbai.soft.service.OrderService;
import dongbai.soft.service.TransferService;
import dongbai.soft.utils.PageUtils;
import dongbai.soft.utils.R;
import dongbai.soft.utils.getUUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author Kun
 * @email
 * @date 2023-06-21 14:58:04
 */
@RestController
@RequestMapping("")
public class OrderController {
    private final String pre = "Order:";
    private final String province = "Province";
    private final String product = "Product:";
    @Autowired
    ShedClient shedClient;
    @Autowired
    CustomerClient customerClient;
    @Autowired
    private OrderService orderService;
    @Autowired
    private TransferService transferService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    /**
     * 给各个模块的总表
     */
    @RequestMapping("/orderlist")
    public R list(@RequestBody Map<String, Object> params) {
        PageUtils page = orderService.queryPage(params);
        List<OrderEntity> list = (List<OrderEntity>) page.getList();
        list = list.stream().map(info -> {
            info.setStaword(staword(info.getIsend(), info.getStatus()));
            return info;
        }).collect(Collectors.toList());
        page.setList(list);
        return R.ok().put("page", page);
    }

    /**
     * 新建订单 ✔
     */
    @RequestMapping("/add")
    public R addOrder(@RequestBody OrderEntity orderEntity) {
        if (orderEntity.getOid() != null) {
            redisTemplate.opsForList().remove("reject", 1, orderEntity.getOid());
        }
        orderEntity.setOid(getUUID.get8UUID());
        orderEntity.setOrderDate(new Date());
        orderEntity.setIsend(0);
        orderEntity.setStatus(1);
        List<TransferEntity> transferlist = transferService.list(new QueryWrapper<TransferEntity>()
                .eq("location", orderEntity.getAddress().split(",")[0]));
        if (transferlist.size() == 0) {
            return R.error("匹配不到分站");
        }
        int n = new Random().nextInt(transferlist.size());
        orderEntity.setTrid(transferlist.get(n).getTrid());
        orderService.save(orderEntity);
        Map<String, String> map = new HashMap<>();
        map.put("OID", orderEntity.getOid());
        map.put("CID", orderEntity.getCid());
        customerClient.addCorder(map);
        return R.ok();

    }

    /**
     * 取消订单 ✔
     */
    @RequestMapping("/cancel")
    public R cancelOrder(@RequestBody Map<String, Object> map) {
        String oid = (String) map.get("OID");
        if (map.get("PID") != null) {
            redisTemplate.opsForList().remove(pre + (String) map.get("PID"), 0, oid);
            if (redisTemplate.opsForList().index(pre + (String) map.get("PID"), 0) == null) {
                redisTemplate.delete(pre + "PID");
            }
        }
        return orderService.cancelOrder(oid, (Integer) map.get("status"));
    }

    /**
     * 查看特定客戶的订单 ✔，
     */
    @RequestMapping("/corderlist")
    public R customerOrderList(@RequestBody Map<String, String> map) {
        List<String> orderlist = new ArrayList<>(Arrays.asList(map.get("orders").split(",")));
        return orderService.queryCOrderList(orderlist);
    }

    /**
     * 请求待办事项(客服) ✔
     */
    @RequestMapping("/todoc")
    public R todoC() {
        List<String> oids = redisTemplate.opsForList().range("reject", 0, -1);
        return R.ok().put("list", oids);
    }

    /**
     * 请求待办事项(库房) ✔
     */
    @RequestMapping("/todos")
    public R todoS() {
        Set<String> pids = redisTemplate.keys(pre + "*");
        List<String> oids = new ArrayList<>();
        for (String pid : pids) {
            oids.addAll(Objects.requireNonNull(redisTemplate.opsForList().range(pid, 0, -1)));
        }
        return R.ok().put("list", oids);
    }

    /**
     * 请求单个订单信息 ✔
     */
    @RequestMapping("/orderinfo")
    public R orderInfo(@RequestBody Map<String, String> oid) {
        return orderService.getOneOrder(oid.get("OID"));
    }


    /**
     * 由其他模块调用本接口
     * 修改订单状态 ✔
     */
    @RequestMapping("/setstatus")
    public R setStatus(@RequestBody Map<String, Object> smap) {
        int isend = (int) smap.get("isend");
        int status = 0;
        String oid = (String) smap.get("OID");
        UpdateWrapper<OrderEntity> upw = new UpdateWrapper<OrderEntity>().eq("OID", oid)
                .set("isend", isend);
        if (smap.get("status") != null) {
            status = (int) smap.get("status");
            upw.set("status", status);
        }

        if (isend == 0) {
            if (status == 0) {//需要挂起该订单
                upw.set("exam_date", new Date());//审批时间
                redisTemplate.opsForList().rightPush(pre + smap.get("PID"), oid);
            } else if (status == 2) {//审批时间
                upw.set("exam_date", new Date());
            } else if (status == 4) {
                upw.set("trans_date", new Date());//到站时间
                ChinaMap((String) smap.get("TRID"), 0);
            }

        } else if (isend == 1) {
            if (status == 0) {
                OrderEntity o = orderService.getById(oid);
                if (shedClient.manual((String) smap.get("PID"))) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("PID", o.getPid());
                    map.put("num", o.getPnum());
                    map.put("status", 3);
                    shedClient.editnum(map);
                } else {
                    orderService.update(upw);
                    return R.error(300, "需要手动调度该商品");
                }

            } else if (status == 1) {//审批拒绝
                upw.set("exam_date", new Date());
                redisTemplate.opsForList().rightPush("reject", oid);
            } else if (status == 2) {
                if (smap.get("TRID") != null) {//入站时间
                    upw.set("trans_date", new Date());
                    ChinaMap((String) smap.get("TRID"), 0);
                } else {//拒签时间
                    upw.set("finish_date", new Date());
                }

            } else if (status == 4) {//签收时间
                upw.set("finish_date", new Date());
                int pnum = (int) smap.get("pnum");
                BigDecimal price = new BigDecimal(smap.get("price") + "");
                outProduct(pnum, price);
            }
        } else {//需要批量结算
            orderService.update(new UpdateWrapper<OrderEntity>().in("OID", (List<String>) smap.get("OIDS")).set("isend", 2));
            return R.ok();
        }
        orderService.update(upw);
        return R.ok();
    }

    /**
     * 由库房来调用本接口
     * 修改挂起订单 ✔
     */
    @RequestMapping("/editShortOrder")
    public R eSOrder(@RequestBody Map<String, Object> pmap) {
        Integer num = (Integer) pmap.get("num");
        Integer ini = num;
        String pid = pre + (String) pmap.get("PID");
        UpdateWrapper<OrderEntity> oqw = new UpdateWrapper<>();
        while (true) {
            OrderEntity o = orderService.getById(redisTemplate.opsForList().leftPop(pid));
            if (o == null) {
                redisTemplate.delete(pid);
                break;
            }
            if (o.getPnum() <= num) {
                num -= o.getPnum();
                orderService.update(oqw.eq("OID", o.getOid()).set("status", 2));

            } else {
                redisTemplate.opsForList().leftPush(pid, o.getOid());
                break;
            }
        }
        if (!ini.equals(num)) {
            Map<String, Object> map = new HashMap<>();
            map.put("PID", pmap.get("PID"));
            map.put("num", num);
            map.put("status", 5);
            shedClient.editnum(map);
        }

        return R.ok();
    }

    /**
     * 出库 + 出库时间 ✔
     */
    @RequestMapping("/send")
    public R sendGood(@RequestBody Map<String, Object> message) {
        orderService.update(new UpdateWrapper<OrderEntity>().eq("OID", message.get("OID"))
                .set("start_date", new Date())
                .set("deliver_price", message.get("deliver_price"))
                .set("status", 3)
        );
        ChinaMap((String) message.get("TRID"), 1);
        return R.ok();
    }

    /**
     * 由分站来调用本接口
     * 出站 + 出站时间 ✔
     */
    @RequestMapping("/delivery")
    public R deliverGood(@RequestBody Map<String, String> delivery) {
        orderService.update(new UpdateWrapper<OrderEntity>().eq("OID", delivery.get("OID"))
                .set("out_trans_date", new Date())
                .set("DID", delivery.get("DID"))
                .set("dName", delivery.get("dName"))
                .set("status", 5)
        );
        return R.ok();
    }

    @RequestMapping("/visual")
    public R mapInfo() {

        //拿到所有省的数据
        List<StaticsEntity> stalist = new ArrayList<>();
        for (int i = 0; i < 31; i++) {
            String[] data = redisTemplate.opsForList().index(province, i).split(",");
            stalist.add(new StaticsEntity(data[0], Integer.parseInt(data[1]), Integer.parseInt(data[2])));
        }

        //拿到TOP8的省名
        List<String> top = new ArrayList<>();
        for (int i = 30; i > 22; i--) {
            top.add(redisTemplate.opsForList().index(province, i).split(",")[0]);
        }
        return Objects.requireNonNull(R.ok().put("map", stalist)).put("lines", top);
    }

    @RequestMapping("/multipleline")
    public R lineInfo() {
        List<String> outnum = redisTemplate.opsForList().range(product + "outnum", 0, 6);
        List<String> outprice = redisTemplate.opsForList().range(product + "outprice", 0, 6);
        List<String> innum = redisTemplate.opsForList().range(product + "innum", 0, 6);
        List<String> inprice = redisTemplate.opsForList().range(product + "inprice", 0, 6);

        List<LineEntity> llist = new ArrayList<>();
        llist.add(new LineEntity("商品出库总量", outnum));
        llist.add(new LineEntity("商品出库总价", outprice));
        llist.add(new LineEntity("商品进货总量", innum));
        llist.add(new LineEntity("商品进货总价", inprice));
        return R.ok().put("list", llist);
    }


    //出库商品数量及总价
    private void outProduct(int pnum, BigDecimal price) {
        int ou = Integer.parseInt(Objects.requireNonNull(redisTemplate.opsForList().index(product + "outnum", 7)));
        BigDecimal op = new BigDecimal(Objects.requireNonNull(redisTemplate.opsForList().index(product + "outprice", 7)));
        pnum += ou;
        price = price.add(op);
        redisTemplate.opsForList().set(product + "outnum", 7, pnum + "");
        redisTemplate.opsForList().set(product + "outprice", 7, price + "");
    }

    //中国地图
    private void ChinaMap(String TRID, int key) {
        String location = transferService.getById(TRID).getLocation();//获取地点名
        List<String> slist = redisTemplate.opsForList().range(province, 0, -1);
        List<StaticsEntity> stalist = new ArrayList<>();

        for (String s : slist) {//把数据拿出来
            String[] d = s.split(",");
            if (d[0].equals(location)) {
                if (key == 0) {//入站
                    stalist.add(new StaticsEntity(d[0], Integer.parseInt(d[1]) + 1, Integer.parseInt(d[2]) - 1));
                } else {//出库
                    stalist.add(new StaticsEntity(d[0], Integer.parseInt(d[1]), Integer.parseInt(d[2]) + 1));
                }
                continue;
            }
            stalist.add(new StaticsEntity(d[0], Integer.parseInt(d[1]), Integer.parseInt(d[2])));

        }
        stalist.sort(Comparator.comparing(StaticsEntity::getValue2));
        for (int i = 0; i < 31; i++) {//把数据塞回去
            redisTemplate.opsForList().set(province, i, stalist.get(i).getName() + "," + stalist.get(i).getValue() + "," + stalist.get(i).getValue2());
        }

    }


    //中文名字映射
    private String staword(int isend, int status) {
        String s = "";
        if (isend == 0 && status == 0) s = "挂起";
        else if (isend == 0 && status == 1) s = "待审批";
        else if (isend == 0 && status == 2) s = "待发货";
        else if (isend == 0 && status == 3) s = "待入站";
        else if (isend == 0 && status == 4) s = "待出站";
        else if (isend == 0 && status == 5) s = "待签收";
        else if (isend == 1 && status == 0) s = "退货完毕";
        else if (isend == 1 && status == 1) s = "审批拒绝";
        else if (isend == 1 && status == 2) s = "在分站";
        else if (isend == 1 && status == 3) s = "待入仓库";
        else if (isend == 1 && status == 4) s = "签收";
        else if (isend == 1 && status == 5) s = "待入站";
        else if (isend == 2 && status == 0) s = "已结算(退货)";
        else if (isend == 2 && status == 4) s = "已结算(签收)";
        return s;
    }

    @RequestMapping("/yeah")
    public void addL() {
        redisTemplate.opsForList().leftPush(province, "黑龙江省,1,2");
        redisTemplate.opsForList().leftPush(province, "吉林省,3,10");
        redisTemplate.opsForList().leftPush(province, "辽宁省,2,7");
        redisTemplate.opsForList().leftPush(province, "河北省,9,2");
        redisTemplate.opsForList().leftPush(province, "甘肃省,7,100");
        redisTemplate.opsForList().leftPush(province, "青海省,3,44");
        redisTemplate.opsForList().leftPush(province, "陕西省,21,63");
        redisTemplate.opsForList().leftPush(province, "河南省,3,22");
        redisTemplate.opsForList().leftPush(province, "山东省,9,11");
        redisTemplate.opsForList().leftPush(province, "山西省,33,1");
        redisTemplate.opsForList().leftPush(province, "安徽省,44,84");
        redisTemplate.opsForList().leftPush(province, "湖北省,12,43");
        redisTemplate.opsForList().leftPush(province, "湖南省,4,42");
        redisTemplate.opsForList().leftPush(province, "江苏省,6,36");
        redisTemplate.opsForList().leftPush(province, "四川省,12,66");
        redisTemplate.opsForList().leftPush(province, "贵州省,7,71");
        redisTemplate.opsForList().leftPush(province, "云南省,41,12");
        redisTemplate.opsForList().leftPush(province, "浙江省,34,32");
        redisTemplate.opsForList().leftPush(province, "江西省,1,3");
        redisTemplate.opsForList().leftPush(province, "广东省,7,5");
        redisTemplate.opsForList().leftPush(province, "福建省,9,8");
        redisTemplate.opsForList().leftPush(province, "海南省,76,1");
        redisTemplate.opsForList().leftPush(province, "新疆,33,257");
        redisTemplate.opsForList().leftPush(province, "内蒙古,8,5");
        redisTemplate.opsForList().leftPush(province, "宁夏,9,3");
        redisTemplate.opsForList().leftPush(province, "广西省,4,2");
        redisTemplate.opsForList().leftPush(province, "西藏,3,0");
        redisTemplate.opsForList().leftPush(province, "北京市,1,100");
        redisTemplate.opsForList().leftPush(province, "上海市,6,1");
        redisTemplate.opsForList().leftPush(province, "天津市,3,123");
        redisTemplate.opsForList().leftPush(province, "重庆市,5,4");

        redisTemplate.opsForList().leftPush("Product:outprice", "1");
        redisTemplate.opsForList().leftPush("Product:outprice", "2");
        redisTemplate.opsForList().leftPush("Product:outprice", "3");
        redisTemplate.opsForList().leftPush("Product:outprice", "4");
        redisTemplate.opsForList().leftPush("Product:outprice", "5");
        redisTemplate.opsForList().leftPush("Product:outprice", "6");
        redisTemplate.opsForList().leftPush("Product:outprice", "7");
        redisTemplate.opsForList().leftPush("Product:outprice", "8");

        redisTemplate.opsForList().leftPush("Product:outnum", "10");
        redisTemplate.opsForList().leftPush("Product:outnum", "20");
        redisTemplate.opsForList().leftPush("Product:outnum", "30");
        redisTemplate.opsForList().leftPush("Product:outnum", "40");
        redisTemplate.opsForList().leftPush("Product:outnum", "50");
        redisTemplate.opsForList().leftPush("Product:outnum", "60");
        redisTemplate.opsForList().leftPush("Product:outnum", "70");
        redisTemplate.opsForList().leftPush("Product:outnum", "80");

        redisTemplate.opsForList().leftPush("Product:innum", "11");
        redisTemplate.opsForList().leftPush("Product:innum", "22");
        redisTemplate.opsForList().leftPush("Product:innum", "33");
        redisTemplate.opsForList().leftPush("Product:innum", "44");
        redisTemplate.opsForList().leftPush("Product:innum", "55");
        redisTemplate.opsForList().leftPush("Product:innum", "66");
        redisTemplate.opsForList().leftPush("Product:innum", "77");
        redisTemplate.opsForList().leftPush("Product:innum", "88");

        redisTemplate.opsForList().leftPush("Product:inprice", "1");
        redisTemplate.opsForList().leftPush("Product:inprice", "22");
        redisTemplate.opsForList().leftPush("Product:inprice", "33");
        redisTemplate.opsForList().leftPush("Product:inprice", "44");
        redisTemplate.opsForList().leftPush("Product:inprice", "55");
        redisTemplate.opsForList().leftPush("Product:inprice", "66");
        redisTemplate.opsForList().leftPush("Product:inprice", "77");
        redisTemplate.opsForList().leftPush("Product:inprice", "88");
    }


}
